﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ArmyBuilder_Modele;
using System.Diagnostics;
using SwapOffice;

namespace ArmyBuilder_DAO
{   
    public class Data<I,M> where I:IObjectModele<I> where M:I,new()
    {
        protected List<I> m_listData;
        
        protected Data()
        {
            m_listData = new List<I>();
        }
        
        public List<I> List()
        {
            return m_listData;
        }

        public I Find(string strCode)
        {
            I oFind = m_listData.Find(
                delegate(I oEnCours)
                {
                    return oEnCours.Code == strCode;
                });

            return oFind;
        }

        public bool Create(I oNew)
        {
            if( Find(oNew.Code) != null )
            {
                m_listData.Add( oNew );
                return true;
            }
            return false;
        }

        public bool Delete(I oNew)
        {
            if( Find(oNew.Code) != null )
            {
                m_listData.Remove( oNew );
                return true;
            }
            return false;
        }

        public bool Update(I oUpdate)
        {
            I oFind = Find(oUpdate.Code);
            if( oFind !=  null )
            {
                oFind = oUpdate;
                return true;
            }

            return false;
        }
    }

    /// <summary>
    /// Classe data d'une race
    /// </summary>
    public class RaceData<M> : Data<IRaceModele,M> where M:IRaceModele,new()
    {
        public RaceData() : base()
        {   
            object[,] tabInit = 
            {   
            { "Humain" },
            { "Elfe" },
            { "Nain" },
            };
                    
            IRaceModele oObj;
            for(int i=0; i<tabInit.GetLength(0); i++)
            {                
                oObj = new M();  
                oObj.Initialise((string)tabInit[i,0]);
                m_listData.Add(oObj);
            }
        }
    }   
        
    /// <summary>
    /// Classe data d'une catégorie
    /// </summary>
    public class CategorieData<M> : Data<ICategorieModele,M> where M:ICategorieModele,new()
    {        
        public CategorieData() : base()
        {   
            object[,] tabInit = 
            {   
            { "Seigneur" },
            { "Héros" },
            { "Base" },
            { "Spécial" },
            { "Rare" },
            };

            ICategorieModele oObj;
            for(int i=0; i<tabInit.GetLength(0); i++)
            {                
                oObj = new M();  
                oObj.Initialise((string)tabInit[i,0]);
                m_listData.Add(oObj);
            }
        }
    }
    
    /// <summary>
    /// Classe data d'une armée
    /// </summary>
    public class ArmeeData<M> : Data<IArmeeModele,M> where M:IArmeeModele,new()
    {
        public ArmeeData() : base(){}

        public void ImportInfoArmee()
        {
            BinderExcel obinderExcelArmee = new BinderExcel(Environment.CurrentDirectory+"\\Army.xlsx");
            if( obinderExcelArmee != null )
            {
            }
        }
    }

    /// <summary>
    /// Classe data d'une Unite
    /// </summary>
    public class UniteData<M> : Data<IUniteModele,M> where M:IUniteModele,new()
    {   
        public UniteData() : base()
        {   
            List<IFigurineModele> listFigurine = new List<IFigurineModele>();

            object[,] tabInit = 
            {   
            { "Hallebardier", "Humain", "Base", 1, 1, true, listFigurine },
            { "Lanciers", "Humain", "Base", 2, 2, true, listFigurine },
            { "Epeiste", "Humain", "Base", 3, 3, true, listFigurine }           
            };

            IUniteModele oObj;
            for(int i=0; i<tabInit.GetLength(0); i++)
            {                
                oObj = new M();  
                oObj.Initialise(
                    (string)tabInit[i,0], 
                    (string)tabInit[i,1],
                    (string)tabInit[i,2],
                    (int)tabInit[i,3],
                    (int)tabInit[i,4],
                    (bool)tabInit[i,5],
                    (List<IFigurineModele>)tabInit[i,6]
                    );
                m_listData.Add(oObj);
            }
        }        

        public List<IUniteModele> GetListUnite(string strRace, string strCategorie)
        {
            List<IUniteModele> listUniteIndex = new List<IUniteModele>();
            
            foreach( IUniteModele oUnite in List() )
            {
                if( oUnite == null ) continue;
                if( oUnite.strRace == strRace && oUnite.strCategorie == strCategorie )
                {
                    listUniteIndex.Add( (IUniteModele)oUnite.Clone() );
                }
            }
            return listUniteIndex;                       
        }        
    }

    /// <summary>
    /// Classe data d'une figurine
    /// </summary>
    public class FigurineData<M> : Data<IFigurineModele,M> where M:IFigurineModele,new()
    {
        public FigurineData() : base(){}
    }

    /// <summary>
    /// Classe data d'un type de figurine
    /// </summary>
    public class TypeFigurineData<M> : Data<ITypeFigurineModele,M> where M:ITypeFigurineModele,new()
    {
        public TypeFigurineData() : base()
        {   
            object[,] tabInit = 
            {   
            { "Infanterie" },
            { "Cavalerie"  },
            { "Machine de guerre" }           
            };

            ITypeFigurineModele oObj;
            for(int i=0; i<tabInit.GetLength(0); i++)
            {                
                oObj = new M();  
                oObj.Initialise(
                    (string)tabInit[i,0]                     
                    );
                m_listData.Add(oObj);
            }           
        }
    }

    /// <summary>
    /// Classe data d'un élément de figurine
    /// </summary>
    public class EltUniteData<I,M> : Data<I,M> where I:IEltUniteModele<I> where M:I,new()
    {
        //public EltUniteData() : base(){}
    }

    /// <summary>
    /// Classe data d'un équipement de figurine
    /// </summary>
    public class EquipementData<M> : EltUniteData<IEquipementModele,M> where M:IEquipementModele,new()
    {
        public EquipementData() : base(){}
    }

    /// <summary>
    /// Classe data d'objet magique d'unité
    /// </summary>
    public class ObjetMagiqueData<M> : EltUniteData<IObjetMagiqueModele,M> where M:IObjetMagiqueModele,new()
    {
        public ObjetMagiqueData() : base(){}
    }

    /// <summary>
    /// Classe data de règle spéciale d'unité
    /// </summary>
    public class RegleSpecialData<M> : EltUniteData<IRegleSpecialModele, M> where M:IRegleSpecialModele,new()
    {
        public RegleSpecialData() : base()
        {
            object[,] tabInit = {   { "Détachement" },
                                    { "Régiment"    }   
                                };

            IRegleSpecialModele oRegle;
            foreach( object[] tab in tabInit )
            {                
                oRegle = new M();  
                oRegle.Initialise((string)tab[0]);
                m_listData.Add(oRegle);
            }
        }
    }

    /// <summary>
    /// Classe data d'option d'unité
    /// </summary>
    public class OptionUniteData<M> : EltUniteData<IOptionUniteModele,M> where M:IOptionUniteModele,new()
    {
        public OptionUniteData() : base(){}
    }
}
